package com.raymond.sgip.session;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.raymond.client.handler.RecvBusinessHandler;
import com.raymond.client.handler.RespBusinessHandler;
import com.raymond.client.msg.BaseMessage;
import com.raymond.client.msg.MessageManages;
import com.raymond.client.netty.MsgDecoder;
import com.raymond.client.netty.MsgEncoder;
import com.raymond.client.service.Callback;
import com.raymond.client.session.AbstractClientSession;
import com.raymond.client.thread.ThreadPool;
import com.raymond.client.utils.CachedMillisecondClock;
import com.raymond.client.utils.SequenceIdUtil;
import com.raymond.sgip.codec.decoding.SgipAgreementDecoder;
import com.raymond.sgip.config.SgipClientSocketConfig;
import com.raymond.sgip.msg.AbstractSgipMessage;
import com.raymond.sgip.msg.request.ConnectRequestMessage;
import com.raymond.sgip.msg.request.TerminateRequestMessage;
import com.raymond.sgip.msg.response.ConnectResponseMessage;
import io.netty.channel.Channel;
import io.netty.channel.ChannelPipeline;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;

/**
 * 简单的mq连接session
 *
 * @author :  raymond
 * @version :  V1.0
 * @date :  2022-11-01 10:25
 */
public class SgipClientSession extends AbstractClientSession {

    private static final Logger logger = LoggerFactory.getLogger(SgipClientSession.class);

    private int loginStatus = -1;

    private int gateId;

    SgipClientSession(SgipClientSessionManager sessionManager, SgipClientSocketConfig socketConfig) {
        super(sessionManager, socketConfig);
        this.gateId = socketConfig.getGateId();
    }

    @Override
    protected void fireChannelActive(Channel channel) {
        ChannelPipeline pipeline = channel.pipeline();
        SgipClientSessionManager sessionManager = (SgipClientSessionManager)super.sessionManager;
        pipeline.addFirst(new RecvBusinessHandler(sessionManager.getHandlerProcessors(), ThreadPool.CALLBACK.getCallBackThreadPool()));
        pipeline.addFirst(new RespBusinessHandler(msgManager));
        pipeline.addFirst(new MsgEncoder(sessionManager.getCodec()));
        pipeline.addFirst(new MsgDecoder(sessionManager.getCodec()));
        pipeline.addFirst(new SgipAgreementDecoder());
        doLogin();
    }

    private void doLogin() {
        SgipClientSocketConfig socketConfig = (SgipClientSocketConfig) this.socketConfig;
        // TODO 发送连接请求 ,创建密码
        ConnectRequestMessage req = new ConnectRequestMessage(SequenceIdUtil.getSequenceId());
        req.setLoginName(socketConfig.getLoginName());

        req.setLoginPassowrd(socketConfig.getLoginPassword());
        req.setLoginType(socketConfig.getLoginType());
        loginStatus = -2;
        MessageManages messageManages = syncSend(req);
        loginStatus = messageManages.getResp() == null ? -2 : (int) ((ConnectResponseMessage)messageManages.getResp()).getResult();
        logger.info("session Start :Send CmppConnectRequestMessage seq :{}, messageManages:{}",
                req.getSequenceId(), JSONObject.toJSONString(messageManages));
    }

    @Override
    public MessageManages syncSend(BaseMessage req) {
        AbstractSgipMessage messageReq = (AbstractSgipMessage) req;
        messageReq.setGateId(gateId);
        messageReq.setTimeStamp(getTimeString(CachedMillisecondClock.INS.now()));
        return super.syncSend(messageReq);
    }

    @Override
    public void asyncSend(BaseMessage req, Callback callback) {
        AbstractSgipMessage messageReq = (AbstractSgipMessage) req;
//        messageReq.setGateId(gateId);
//        messageReq.setTimeStamp(getTimeString(CachedMillisecondClock.INS.now()));
        super.asyncSend(messageReq, callback);
    }

    @Override
    public void asyncSend(MessageManages messageManages) {
        AbstractSgipMessage messageReq = (AbstractSgipMessage) messageManages.getReq();
        messageReq.setGateId(gateId);
        messageReq.setTimeStamp(getTimeString(CachedMillisecondClock.INS.now()));
        super.asyncSend(messageManages);

    }

    @Override
    public synchronized void shutdown() throws InterruptedException {
        syncSend(new TerminateRequestMessage(SequenceIdUtil.getSequenceId()));
        super.shutdown();
    }

    public int getLoginStatus() {
        return loginStatus;
    }

    public int getTimeString(long timeMillis) {
        return Integer.parseInt(DateUtil.format(new Date(timeMillis), "MMddHHmmss"));
    }
}
